package com.example.algorithm.greedy;

import java.util.Arrays;
import java.util.Comparator;

/**
 * 在二维空间中有许多球形的气球。对于每个气球，提供的输入是水平方向上，气球直径的开始和结束坐标。由于它是水平的，所以纵坐标并不重要，因此只要知道开始和结束的横
 * 坐标就足够了。开始坐标总是小于结束坐标。
 *
 *  一支弓箭可以沿着 x 轴从不同点完全垂直地射出。在坐标 x 处射出一支箭，若有一个气球的直径的开始和结束坐标为 xstart，xend，
 *  且满足xstart ≤ x ≤ xend，则该气球会被引爆。可以射出的弓箭的数量没有限制。 弓箭一旦被射出之后，可以无限地前进。
 *  我们想找到使得所有气球全部被引爆，所需的弓箭的最小数量。
 *
 *  给你一个数组 points ，其中 points [i] = [xstart,xend] ，返回引爆所有气球所必须射出的最小弓箭数。
 *
 *
 *  示例 1：
 * 输入：points = [[10,16],[2,8],[1,6],[7,12]]
 * 输出：2
 * 解释：对于该样例，x = 6 可以射爆 [2,8],[1,6] 两个气球，以及 x = 11 射爆另外两个气球
 *
 *  示例 2：
 * 输入：points = [[1,2],[3,4],[5,6],[7,8]]
 * 输出：4
 *
 *  示例 3：
 * 输入：points = [[1,2],[2,3],[3,4],[4,5]]
 * 输出：2
 */
public class Leetcode452_FindMinArrowShots {
    public static void main(String[] args) {
        int[][] points = {{10, 16}, {2, 8}, {1, 6}, {7, 12}};
        points = new int[][] {{3,9},{7,12},{3,8},{6,8},{9,10},{2,9},{0,9},{3,9},{0,6},{2,8}};
        System.out.println(new Solution().findMinArrowShots(points));
    }

    static class Solution {
        /**
         * 贪心算法:
         * 每一箭尽可能多的射爆气球
         * @param points
         * @return
         */
        public int findMinArrowShots(int[][] points) {
            if (points == null || points.length == 0) return 0;

            Arrays.sort(points, Comparator.comparingInt(p -> p[1]));

            int border = points[0][1];
            int count = 1;
            for (int[] point : points) {
                if (point[0] > border) { // 当前的这个气球不能被当前这一箭射爆时
                    ++count; // 所需箭数要 +1
                    border = point[1]; // 更新能射到的最"右"的边界(每次都取当前气球最右边界的坐标，可以有更大可能射爆下一个气球)
                }
            }
            return count;
        }
    }
}
